import os
from flask import Flask,request , Response, send_file
from flask_cors import CORS
import requests
import hashlib
import random
import string
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
import asyncio
import mimetypes
import threading
import time
from urllib.parse import unquote
import qrcode
import json
import whois
from datetime import datetime
import re
import shutil


app = Flask(__name__)
CORS(app)

visit_request = {}
user_server = 'http://user.hackerstack.top'


def contains_script_or_link_tags(html_text):
    # 正则表达式匹配可能被转义的<script>和<link>标签
    script_pattern = re.compile(r'&lt;script.*?&gt;|<script.*?>', re.IGNORECASE)
    link_pattern = re.compile(r'&lt;link.*?&gt;|<link.*?>', re.IGNORECASE)

    # 检测是否有匹配的<script>标签
    script_match = script_pattern.search(html_text)
    # 检测是否有匹配的<link>标签
    link_match = link_pattern.search(html_text)

    # 如果任一标签被找到，返回True
    if script_match or link_match:
        return True
    else:
        return False

def shuffle_dict_values(content_list):
    # 提取字典的所有值到一个列表中
    values_list = list(content_list.values())
    
    # 打乱列表的顺序
    random.shuffle(values_list)
    
    # 创建一个新的字典，保持键和打乱后的值对应
    shuffled_dict = {key: value for key, value in zip(content_list.keys(), values_list)}
    
    return shuffled_dict

def list_dir_file_number(path):
    if not os.path.exists(os.path.dirname(path)):
        # 如果不存在，创建目录
        os.makedirs(os.path.dirname(path))
        return 0
    return len(os.listdir(os.path.dirname(path)))  

def copy_files_with_structure(src_folder, dst_folder):
    # 遍历源文件夹中的所有文件和目录
    for root, dirs, files in os.walk(src_folder):
        # 对于源文件夹中的每个文件
        for file in files:
            # 构建源文件的完整路径
            src_file_path = os.path.join(root, file)
            # 构建目标文件的完整路径
            dst_file_path = src_file_path.replace(src_folder, dst_folder)
            # 创建目标文件的目录（如果不存在）
            os.makedirs(os.path.dirname(dst_file_path), exist_ok=True)
            # 复制文件
            shutil.copy2(src_file_path, dst_file_path)
            print(f"文件 '{src_file_path}' 已复制到 '{dst_file_path}'")

@app.route('/get_project_config/<user>/<pwd>/<project_name>')
def get_project_config(user , pwd ,project_name):
    r = requests.post(user_server+'/login' , data=user+"\n"+pwd)
    if r.text != 'Passwd Or UserName Error!':
        pass
    else:
        return '用户名或者密码不正确.'
    return open('./project/'+user+"/"+project_name+"/config.json").read()

@app.route('/list_html_project/<user>/<pwd>/<project_name>' , methods=['POST'])
def list_html_project(user , pwd, project_name):
    url = request.get_data().decode('utf-8').replace("//" , "/")
    r = requests.post(user_server+'/login' , data=user+"\n"+pwd)
    if r.text != 'Passwd Or UserName Error!':
        pass
    else:
        return '用户名或者密码不正确.'
    if '../' in str(url).replace(' ',''):
        return '不得包含类似于 ../ 目录描述符号'
    obj = {}

    l = os.listdir('./project/'+user+"/"+project_name+"/html"+url)
    for i in l:
        name = i
        isFile = ''
        if os.path.isfile('./project/'+user+"/"+project_name+"/html"+url+"/"+i):
            isFile = '文件'
        else:
            isFile = '目录'
        obj[name] = isFile

    return json.dumps(obj)

@app.route('/create/<user>/<pwd>/<check_code>/<type>/<project_name>' , methods=['POST'])
def create_content(user , pwd , check_code,type,project_name):
    # 限制每个IP对制定api的访问.
    client_ip = request.remote_addr
    if client_ip in visit_request:
        visit_request[client_ip] = visit_request[client_ip] + 1
        if visit_request[client_ip] > 2:
            return '请求过多'
    else:
        visit_request[client_ip] = 1

    if list_dir_file_number('./project/'+user) > 3:
        return '项目创建数量不得多于 3 个项目'

    r = requests.post(user_server+'/check_ip_check/'+check_code)
    if json.loads(r.text)['message'] == 'ok':
        pass
    else:
        return '验证码错误'

    r = requests.post(user_server+'/login' , data=user+"\n"+pwd)
    if r.text != 'Passwd Or UserName Error!':
        pass
    else:
        return '用户名或者密码不正确.'
    # 获取文件目录
    now = datetime.now()
    directory = os.path.dirname("./project/"+user+"/"+project_name)

    directory += '/' + project_name
    # 检查目录是否存在，如果不存在则创建
    if not os.path.exists(directory):
        os.makedirs(directory)
        os.makedirs(directory+"/html")
        os.makedirs(directory+"/app")
        copy_files_with_structure("./modules/"+type+"/html", directory+"/"+project_name+"/html/")
        copy_files_with_structure("./modules/"+type+"/app", directory+"/"+project_name+"/app/")
        
        write_obj = {
            "Name" : project_name,
            "Type" : type
        }

        with open(directory+"/config.json" , 'w') as f:
            f.write(json.dumps(write_obj))
    else:
        return '项目已经存在'

    
    return '创建成功'

def debug_server():
    os.system('cd ./project/ && python3 -m http.server 8000')

if __name__ == '__main__':
    import threading
    t = threading.Thread(target=debug_server)
    t.start()
    app.run(host='0.0.0.0' , port=55555)